package ws.jdbc.concurrent.driver.sqlserver.cursor.shared

import static java.sql.ResultSet.*
import ws.jdbc.concurrent.driver.sqlserver.*
import java.util.concurrent.atomic.AtomicInteger

/**
 * Test case of CursorForwardOnlyUpdatable class methods.
 *
 * @author Wilson Santos, 36228 <wilson.santos@ua.pt>
 */
class CursorForwardOnlyUpdatableTest extends ForwardOnlyUpdatableTest {
  AtomicInteger counter
  
  /**
   * Run this before every test.
   */
  @Override
  void setUp() {
    super.setUp()

    stmt = con.createStatement(TYPE_FORWARD_ONLY, CONCUR_UPDATABLE)
    stmt.setFetchSize(0)
    stmt.executeQuery(sqlQuery)
    rs = stmt.getCursor()

    assertNotNull rs
    assertTrue rs instanceof CursorForwardOnlyUpdatable

    counter = new AtomicInteger()
  }

  /**
   * Test of updateRow() method for multiple threads.
   */
  void testUpdateRowThreads() {
    println "testUpdateRowThreads()"

    runThreads {
      def c = stmt.getCursor()
      def line = counter.incrementAndGet()
      line.times {
        c.next()
      }

      def val = rand.nextInt(50)
      c.updateInt(1, val)
      c.updateString(2, "val ${val}")
      c.updateRow()

      assertLineValuesMatch c, line, val, "val ${val}"

      c.refreshRow()
      assertLineValuesMatch c, line, val, "val ${val}" // assert that the value on the table is correct.
    }
  }

  /**
   * Test of insertRow() method for multiple threads.
   */
  void testInsertRowThreads() {
    println "testInsertRowThreads()"

    DataTest.table.size().times {
      rs.next()
    }

    def newRows = new ArrayList<Integer>(nthreads)

    runThreads {
      def line = counter.incrementAndGet()
      def c = stmt.getCursor()
      def curRow = c.getRow()

      c.moveToInsertRow()

      def val = rand.nextInt(50)
      c.updateInt(1, val)
      c.updateString(2, "val ${val}")

      c.insertRow()

      c.moveToCurrentRow()

      assertEquals curRow, c.getRow()

      synchronized(newRows) {
        newRows.add(val)
      }
    }

    // Assert that the rows were indeed insert
    nthreads.times {
      rs.next()
      assertTrue newRows.contains(rs.getInt(1))
    }
  }
}